package api

import (
	"TaskAssignmentSystem/internal/admin/dao"
	"TaskAssignmentSystem/internal/app/services"
	"TaskAssignmentSystem/internal/pkg/middleware/handler"
	"TaskAssignmentSystem/pkg/db/redis"
	"TaskAssignmentSystem/pkg/oss"
	"TaskAssignmentSystem/pkg/utils"
	"errors"
	"fmt"
	"github.com/kataras/iris/v12"
	"io/ioutil"
	"strconv"
	"strings"
	"time"
)

// @Summary 用户个人信息
// @Description 用户个人信息
// @Tags 用户
// @Accept application/json
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /app/user/info [get]
func UserInfoHandler(ctx iris.Context) {

	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	var userServe services.SystemUserService
	if res, err := userServe.UserInfo(claims.Id); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: res})
		return
	}
}

type UpdateAvatarRequest struct {
}

// @Summary 更新头像
// @Description 更新头像
// @Tags 用户
// @Accept multipart/form-data
// @Produce application/json
// @param Accept-Version header string true "1.0.0"
// @param Authorization header string true "验证参数Bearer和token空格拼接"
// @Param file formData file true "更新头像参数"
// @Success 200 {object} utils.Response --> 成功后返回数据结构
// @Failure 400 {object} utils.ResponseError --> 失败后返回数据结构
// @Router /app/user/update_avatar [post]
func UpdateAvatarHandler(ctx iris.Context) {
	_, handle, err := utils.FormFile(ctx, "file")
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	file, err := handle.Open()
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}

	//获取当前时间的月份
	currentMonth := time.Now().In(utils.LocationZone).Format("2006-01")

	//关闭打开文件
	defer file.Close()
	fileByte, err := ioutil.ReadAll(file) //获取上传文件字节流
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}

	//查询当前用户的头像
	var user dao.Common[dao.SystemUser]
	user.Query = map[string]interface{}{"id": claims.Id}
	systemUser, err := user.First(user.Query)
	if strings.Contains(systemUser.Avatar, fmt.Sprintf("task-assign/avatar/%s", currentMonth)) {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: "头像一月只能更换一次！"})
		return
	}

	var ossClient oss.BucketClient
	if handle.Filename == "image.jpg" {
		handle.Filename = fmt.Sprintf("%d.jpeg", time.Now().Unix())
	}

	fileName := fmt.Sprintf("task-assign/avatar/%s/%s", currentMonth, handle.Filename)
	if err := ossClient.UpBytes(fileByte, fileName); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		var user dao.Common[dao.SystemUser]
		user.Query = map[string]interface{}{"id": claims.Id}
		if err := user.Update(map[string]interface{}{"avatar": fmt.Sprintf("%s/%s", utils.ServerConf.AliOssConf.CallBackHost, fileName)}).Error; err != nil {
			ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
			return
		} else {
			ctx.JSON(utils.Response{Code: iris.StatusOK, Message: iris.StatusText(iris.StatusOK), Data: fmt.Sprintf("%s/%s", utils.ServerConf.AliOssConf.CallBackHost, fileName)})
			return
		}

	}
}

//请求频次限制

func UserRequestFrequencyLimit(ctx iris.Context) {
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	frequencyKey := fmt.Sprintf("user_frequency@%d", claims.Id)
	ttl := redis.RedisGClient.TTL(frequencyKey).Val()
	if ttl.Seconds() != -2 {
		//if setNX := redis.RedisGClient.Set(frequencyKey, 5+ttl.Milliseconds()/1000, time.Duration(5+ttl.Milliseconds()/1000)*time.Second).Err(); setNX != nil {
		//	ctx.JSON(utils.Response{Code: iris.StatusTooManyRequests, Message: fmt.Sprintf("您的操作过于频繁，请在%d秒后再试！谢谢！", 5+ttl.Milliseconds()/1000), Data: 5 + ttl.Milliseconds()/1000})
		//	return
		//}
		ctx.JSON(utils.Response{Code: iris.StatusTooManyRequests, Message: fmt.Sprintf("您的操作过于频繁，请在%d秒后再试！谢谢！", ttl.Milliseconds()/1000), Data: ttl.Seconds()})
		return
	} else {
		if setNX := redis.RedisGClient.Set(frequencyKey, 6, time.Duration(6)*time.Second).Err(); setNX != nil {
			ctx.JSON(utils.Response{Code: iris.StatusTooManyRequests, Message: fmt.Sprintf("您的操作过于频繁，请在%d秒后再试！谢谢！", 5), Data: 5})
			return
		}
	}
	ctx.Next()
}

type UserEditSettingsRequest struct {
	// UpType 修改哪个字段
	// 1:实名认证，2:修改邮箱,使用原邮箱修改，3:修改邮箱,使用原手机号修改，
	// 4:修改手机号,使用原手机号修改，5:修改手机号,使用原邮箱修改，6:修改支付宝账户，
	// 7:修改收货地址，8:修改昵称,9:修改简介
	UpType          string `json:"up_type" validate:"required"`
	RealName        string `json:"real_name"`
	IdCardNumber    string `json:"id_card_number"`
	OldCode         string `json:"old_code"`
	NewCode         string `json:"new_code"`
	OldEmail        string `json:"old_email"`
	NewEmail        string `json:"new_email"`
	OldPhone        string `json:"old_phone"`
	NewPhone        string `json:"new_phone"`
	AlipayAccount   string `json:"alipay_account"`
	DeliveryAddress string `json:"delivery_address"`
	NickName        string `json:"nick_name"`
	Introduction    string `json:"introduction"`
}

func Substr(str string, start, length int) string {
	rs := []rune(str)
	rl := len(rs)
	end := 0
	if start < 0 {
		start = rl - 1 + start
	}
	end = start + length
	if start > end {
		start, end = end, start
	}
	if start < 0 {
		start = 0
	}
	if start > rl {
		start = rl
	}
	if end < 0 {
		end = 0
	}
	if end > rl {
		end = rl
	}
	return string(rs[start:end])
}

var mapmou = map[string]int{"January": 1, "february": 2, "March": 3, "April": 4, "May": 5, "June": 6, "July": 7, "August": 8, "September": 9, "October": 10, "November": 11, "December": 12}

func UserEditSettingsHandler(ctx iris.Context) {
	var RequestParams UserEditSettingsRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseServerError(err))
		return
	}
	var userServe services.SystemUserService
	var err error
	var param = make(map[string]string)
	dictCode := "dictCode"
	timeKey := "timeKey"
	param["upType"] = RequestParams.UpType
	if RequestParams.UpType == "1" {
		//1:实名认证
		param[dictCode] = "ZXZ_USER_REAL_NAME_AUTHENTICATION"
		param[timeKey] = "real_name_authentication"
		param["realName"] = RequestParams.RealName
		param["idCardNumber"] = RequestParams.IdCardNumber
		if RequestParams.IdCardNumber != "" {
			idcardYear, _ := strconv.Atoi(Substr(RequestParams.IdCardNumber, 6, 4)) // 年
			idcardMo, _ := strconv.Atoi(Substr(RequestParams.IdCardNumber, 10, 2))  // 月
			idcardDay, _ := strconv.Atoi(Substr(RequestParams.IdCardNumber, 12, 2)) // 日
			now := time.Now()
			nowYear := now.Year()                 // 年
			nowMo := mapmou[now.Month().String()] // 月
			nowDay := now.Day()                   // 日
			// 比较年<16 未成年
			if nowYear-idcardYear < 16 {
				ctx.JSON(utils.ResponseServerError(errors.New("请注意，仅16周岁及以上才可以使用本网站进行实名认证并工作")))
				return
			}
			// 年==16 比较月
			if nowYear-idcardYear == 16 {
				if idcardMo > nowMo {
					ctx.JSON(utils.ResponseServerError(errors.New("请注意，仅16周岁及以上才可以使用本网站进行实名认证并工作")))
					return
				}
				// 年==16 月相同，比较日
				if idcardMo == nowMo {
					if idcardDay >= nowDay {
						ctx.JSON(utils.ResponseServerError(errors.New("请注意，仅16周岁及以上才可以使用本网站进行实名认证并工作")))
						return
					}
				}
			}

		}
	} else if RequestParams.UpType == "2" {
		//2:修改邮箱,使用原邮箱修改
		param[dictCode] = "ZXZ_USER_EMAIL_EDIT"
		param[timeKey] = "email"
		param["oldEmail"] = RequestParams.OldEmail
		param["newEmail"] = RequestParams.NewEmail
		param["oldCode"] = RequestParams.OldCode
		param["newCode"] = RequestParams.NewCode
	} else if RequestParams.UpType == "3" {
		//3:修改邮箱,使用原手机号修改
		param[dictCode] = "ZXZ_USER_EMAIL_EDIT"
		param[timeKey] = "email"
		param["oldPhone"] = RequestParams.OldPhone
		param["newEmail"] = RequestParams.NewEmail
		param["oldCode"] = RequestParams.OldCode
		param["newCode"] = RequestParams.NewCode
	} else if RequestParams.UpType == "4" {
		//4:修改手机号,使用原手机号修改
		param[dictCode] = "ZXZ_USER_PHONE_EDIT"
		param[timeKey] = "phone"
		param["oldPhone"] = RequestParams.OldPhone
		param["newPhone"] = RequestParams.NewPhone
		param["oldCode"] = RequestParams.OldCode
		param["newCode"] = RequestParams.NewCode
	} else if RequestParams.UpType == "5" {
		//5:修改手机号,使用原邮箱修改
		param[dictCode] = "ZXZ_USER_PHONE_EDIT"
		param[timeKey] = "phone"
		param["oldEmail"] = RequestParams.OldEmail
		param["newPhone"] = RequestParams.NewPhone
		param["oldCode"] = RequestParams.OldCode
		param["newCode"] = RequestParams.NewCode
	} else if RequestParams.UpType == "6" {
		//6:修改支付宝账户
		k := "alipay_account"
		param[dictCode] = "ZXZ_USER_ALIPAY_ACCOUNT_EDIT"
		param[timeKey] = k
		param[k] = RequestParams.AlipayAccount
	} else if RequestParams.UpType == "7" {
		//7:修改收货地址
		k := "delivery_address"
		param[dictCode] = "ZXZ_USER_DELIVERY_ADDRESS_EDIT"
		param[timeKey] = k
		param[k] = RequestParams.DeliveryAddress
	} else if RequestParams.UpType == "8" {
		//8:修改昵称
		k := "nick_name"
		param[dictCode] = "ZXZ_USER_NICK_NAME_EDIT"
		param[timeKey] = k
		param[k] = RequestParams.NickName
	} else if RequestParams.UpType == "9" {
		//9:修改简介
		k := "introduction"
		param[dictCode] = "ZXZ_USER_INTRODUCTION_EDIT"
		param[timeKey] = k
		param[k] = RequestParams.Introduction
	} else {
		ctx.JSON(utils.ResponseServerError(errors.New("类型异常")))
		return
	}

	err = userServe.UserEditSettings(claims.Id, param)
	if err != nil {
		ctx.JSON(utils.ResponseServerError(err))
		return
	} else {
		ctx.JSON(utils.ResponseOK())
		return
	}
}

func UpdateIdCardFaceHandler(ctx iris.Context) {
	_, handle, err := utils.FormFile(ctx, "file")
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	file, err := handle.Open()
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}

	//获取当前时间的月份
	currentMonth := time.Now().In(utils.LocationZone).Format("2006-01")

	//关闭打开文件
	defer file.Close()
	fileByte, err := ioutil.ReadAll(file) //获取上传文件字节流
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}

	var ossClient oss.BucketClient
	if handle.Filename == "image.jpg" {
		handle.Filename = fmt.Sprintf("%d.jpeg", time.Now().Unix())
	}

	fileName := fmt.Sprintf("task-assign/idcard/%s/%s", currentMonth, handle.Filename)
	if err := ossClient.UpBytes(fileByte, fileName); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		webPath := fmt.Sprintf("%s/%s", utils.ServerConf.AliOssConf.CallBackHost, fileName)
		if _, err := utils.OCRFace(webPath); err != nil {
			ctx.JSON(utils.ResponseServerError(err))
			return
		}
		var user dao.Common[dao.SystemUser]
		user.Query = map[string]interface{}{"id": claims.Id}
		if err := user.Update(map[string]interface{}{"id_card_face": webPath}).Error; err != nil {
			ctx.JSON(utils.ResponseServerError(err))
			return
		} else {
			ctx.JSON(utils.ResponseData(webPath))
			return
		}
	}
}

func UpdateIdCardBackHandler(ctx iris.Context) {
	_, handle, err := utils.FormFile(ctx, "file")
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	file, err := handle.Open()
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}

	//获取当前时间的月份
	currentMonth := time.Now().In(utils.LocationZone).Format("2006-01")

	//关闭打开文件
	defer file.Close()
	fileByte, err := ioutil.ReadAll(file) //获取上传文件字节流
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}

	var ossClient oss.BucketClient
	if handle.Filename == "image.jpg" {
		handle.Filename = fmt.Sprintf("%d.jpeg", time.Now().Unix())
	}

	fileName := fmt.Sprintf("task-assign/idcard/%s/%s", currentMonth, handle.Filename)
	if err := ossClient.UpBytes(fileByte, fileName); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	} else {
		webPath := fmt.Sprintf("%s/%s", utils.ServerConf.AliOssConf.CallBackHost, fileName)
		if _, err := utils.OCRBack(webPath); err != nil {
			ctx.JSON(utils.ResponseServerError(err))
			return
		}
		var user dao.Common[dao.SystemUser]
		user.Query = map[string]interface{}{"id": claims.Id}
		if err := user.Update(map[string]interface{}{"id_card_back": webPath}).Error; err != nil {
			ctx.JSON(utils.ResponseServerError(err))
			return
		} else {
			ctx.JSON(utils.ResponseData(webPath))
			return
		}
	}
}

type UserGetTopicRequest struct {
	ProjectId   string `json:"project_id"`   // 项目ID
	TopicNumber int    `json:"topic_number"` // 领取数量
}

func UserGetTopicRequestFrequencyLimit(ctx iris.Context) {
	var RequestParams UserGetTopicRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}
	var claims services.CustomClaims
	if err := claims.ParseClaims(ctx); err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}
	if utils.StringIsEmpty(RequestParams.ProjectId) {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: "项目ID不能为空!"})
		return
	}
	if utils.StringIsEmpty(utils.IntToString(RequestParams.TopicNumber)) {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: "领取数量不能为空!"})
		return
	}

	var common dao.Common[dao.SystemUser]
	common.Query = map[string]interface{}{"id": claims.Id}
	user, err := common.First(common.Query)
	if err != nil {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: err.Error()})
		return
	}

	var userProjects []string
	//查询团队表，如果团长设置了只允许查看团队项目，则只查看团队项目
	var teamDao dao.Common[dao.SystemTeam]
	//用户是团长则直接查团队配置
	if teamInfo, err := teamDao.First(map[string]interface{}{"user_id": claims.UserName, "status": 1}); err == nil {
		if utils.StringIsNotEmpty(teamInfo.TeamPermissions) {
			projectIds := strings.Split(teamInfo.TeamPermissions, "，")
			for _, id := range projectIds {
				userProjects = append(userProjects, id)
			}
		} else {
			//团队配置没查到也读用户自己配置
			for _, u := range user.SystemUserRestriction {
				userProjects = append(userProjects, u.ProjectId)
			}
		}
	}
	//用户是团队也查询团队配置
	if utils.StringIsNotEmpty(user.TeamNumber) && user.TeamNumber != "zxz" {
		if teamInfo2, err := teamDao.First(map[string]interface{}{"team_number": user.TeamNumber, "status": 1}); err == nil {
			if utils.StringIsNotEmpty(teamInfo2.TeamPermissions) {
				projectIds := strings.Split(teamInfo2.TeamPermissions, "，")
				for _, id := range projectIds {
					userProjects = append(userProjects, id)
				}
			} else {
				//团队没配置则读用户自己配置
				for _, u := range user.SystemUserRestriction {
					userProjects = append(userProjects, u.ProjectId)
				}
			}
		} else {
			//团队没查到也读用户自己配置
			for _, u := range user.SystemUserRestriction {
				userProjects = append(userProjects, u.ProjectId)
			}
		}
	} else {
		//团队没查到也读用户自己配置
		for _, u := range user.SystemUserRestriction {
			userProjects = append(userProjects, u.ProjectId)
		}
	}
	seeFlag := false
	for _, project := range userProjects {
		if RequestParams.ProjectId == project {
			seeFlag = true
		}
	}

	if !seeFlag {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: "您没有权限"})
		return
	}

	//查领取配置表
	var userRestrictionServ dao.Common[dao.SystemUserRestriction]
	userRestrictionServ.Query = map[string]interface{}{"project_id": RequestParams.ProjectId, "system_user_id": claims.Id}
	if userRestriction, err := userRestrictionServ.First(userRestrictionServ.Query); err == nil {
		//判断是否超过CD
		if userRestriction.Cd > 0 {
			frequencyKey := fmt.Sprintf("user_frequency@%d@%d", claims.Id, userRestriction.Cd)
			ttl := redis.RedisGClient.TTL(frequencyKey).Val()
			if ttl.Seconds() != -2 {
				ctx.JSON(utils.Response{Code: iris.StatusTooManyRequests, Message: fmt.Sprintf("您的操作过于频繁，请在%d秒后再试！谢谢！", ttl.Milliseconds()/1000), Data: ttl.Seconds()})
				return
			} else {
				if setNX := redis.RedisGClient.Set(frequencyKey, userRestriction.Cd, time.Duration(userRestriction.Cd)*time.Second).Err(); setNX != nil {
					ctx.JSON(utils.Response{Code: iris.StatusTooManyRequests, Message: fmt.Sprintf("您的操作过于频繁，请在%d秒后再试！谢谢！", userRestriction.Cd), Data: userRestriction.Cd})
					return
				}
			}
		}

		//判断单次领取数量是否在范围内
		if userRestriction.LowerLimit != 0 && userRestriction.Limit != 0 {
			if RequestParams.TopicNumber < userRestriction.LowerLimit || RequestParams.TopicNumber > userRestriction.Limit {
				msg := fmt.Sprintf("单次领取数量错误！单次领取数量为：%v-%v", userRestriction.LowerLimit, userRestriction.Limit)
				ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: msg})
				return
			}
		}

		//判断总领取数量是否超过当日能领取的上限
		if userRestriction.DayLimit > 0 {
			var topicServ dao.Common[dao.TopicUserRecord]
			sql := fmt.Sprintf("select count(1) total from tas_topic_user_record where user_id = (select user_id from tas_system_user where id = %v) and left(created_at,10) = DATE_FORMAT(NOW(), '%%Y-%%m-%%d') and tp = 1 and project_id = '%v'", claims.Id, RequestParams.ProjectId)
			if amount, err := topicServ.RawCount(sql, "total"); err == nil {
				if amount+int64(RequestParams.TopicNumber) > int64(userRestriction.DayLimit) {
					ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: "已达到今日领取上限，请明日再来"})
					return
				}
			}
		}
	} else {
		ctx.JSON(utils.ResponseError{Code: iris.StatusInternalServerError, Message: "您没有权限"})
		return
	}
	ctx.Next()
}

type UserIdCardIdentifyRequest struct {
	Name   string `json:"name" validate:"required"`    //姓名
	IdCard string `json:"id_card" validate:"required"` //身份证号
}

func UserIdCardIdentifyHandler(ctx iris.Context) {
	var RequestParams UserIdCardIdentifyRequest
	if err := ctx.ReadJSON(&RequestParams); err != nil {
		handler.ArgumentErrorHandle(err, ctx)
		return
	}

	ctx.JSON(utils.ResponseData(utils.IsCheckIDCard(RequestParams.IdCard, RequestParams.Name)))
	return
}
